package session

import (
	"errors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

const (
	NotFound = "session_not_found"
)

type CookieSessionReq struct {
	Key    []byte
	Path   string
	MaxAge int
	Name   string
}

func NewCookieSessionReq() *CookieSessionReq {
	return &CookieSessionReq{Key: []byte("_SESSION"), Path: "/", MaxAge: 24 * 3600, Name: "_SESSION"}
}

func (c *CookieSessionReq) SetKey(key []byte) *CookieSessionReq {
	c.Key = key
	return c
}

func (c *CookieSessionReq) SetPath(path string) *CookieSessionReq {
	c.Path = path
	return c
}

func (c *CookieSessionReq) SetMaxAge(maxAge int) *CookieSessionReq {
	c.MaxAge = maxAge
	return c
}

func (c *CookieSessionReq) SetSessionName(name string) *CookieSessionReq {
	c.Name = name
	return c
}

// EnableCookieSession 使用 Cookie 保存 session
func EnableCookieSession(req *CookieSessionReq) gin.HandlerFunc {
	store := cookie.NewStore(req.Key)
	store.Options(sessions.Options{Path: req.Path, MaxAge: req.MaxAge})
	return sessions.Sessions(req.Name, store)
}

func Set(c *gin.Context, key string, value interface{}) (err error) {
	s := sessions.Default(c)
	s.Set(key, value)
	err = s.Save()
	if err != nil {
		return err
	}
	return nil
}

func Get(c *gin.Context, key string) interface{} {
	s := sessions.Default(c)
	return s.Get(key)
}

func Del(c *gin.Context, key string) error {
	s := sessions.Default(c)
	s.Delete(key)
	return s.Save()
}

func GetSessionId(c *gin.Context) (int64, error) {
	s := sessions.Default(c)
	auth, ok := s.Get("uid").(uint)
	if !ok {
		return 0, errors.New(NotFound)
	}
	return int64(auth), nil
}
